package constant.milk.toilet.widget;

import java.util.Calendar;
import java.util.HashMap;

import constant.milk.toilet.IntroActivity;
import constant.milk.toilet.R;
import constant.milk.toilet.broadcast.PushBroadcast;
import constant.milk.toilet.database.DbAdapter;
import constant.milk.toilet.database.DbInsertQuery;
import constant.milk.toilet.timer.TimerManager;
import constant.milk.toilet.util.MilkUtil;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.ActivityManager.RunningServiceInfo;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.widget.RemoteViews;

public class ToiletWidget extends AppWidgetProvider
{
	public static final String RESET = "constant.milk.toilet.widget.RESET";
	public static final String START = "constant.milk.toilet.widget.START";
	public static final String STOP = "constant.milk.toilet.widget.STOP";
	public static final String SAVE = "constant.milk.toilet.widget.SAVE";
	public static final String TIMER = "constant.milk.toilet.widget.TIMER";
	
	private RemoteViews remoteView;
	
	@Override
	public void onReceive(Context context, Intent intent)
	{
		super.onReceive(context, intent);
		
		String action = intent.getAction();
		
		if (action.equals(RESET))
		{
			Intent service = new Intent(context, WidgetService.class);
			context.stopService(service);
			
			TimerManager tm = new TimerManager();
			tm.stopTimer(context);
			
			setResetData(context);
		}
		else if (action.equals(START))
		{
			if (isServiceRunning("constant.milk.toilet.timer.WidgetService", context))
			{
				return;
			}
			
			SharedPreferences p = context.getSharedPreferences("pref", Activity.MODE_PRIVATE);
			
			int hour = p.getInt(context.getString(R.string.prefHour), 0);
			int min = p.getInt(context.getString(R.string.prefMin), 0);
			int sec = p.getInt(context.getString(R.string.prefSec), 0); 
			
			if (hour >= 23 && min >= 59 && sec >= 59)
			{
				MilkUtil.showToast(context, "최대 시간입니다. 다시 시작 할려면 RESET을 누르고 시작해 주세요.");
				return;
			}
			
			SharedPreferences.Editor e = p.edit();
			e.putLong(context.getString(R.string.prefStartTime), System.currentTimeMillis());
			e.commit();
			
			startTime(context);
		}
		else if (action.equals(STOP))
		{
			Intent service = new Intent(context, WidgetService.class);
			context.stopService(service);
			
			TimerManager tm = new TimerManager();
			tm.stopTimer(context);
			
			SharedPreferences p = context.getSharedPreferences("pref", Activity.MODE_PRIVATE);
			SharedPreferences.Editor e = p.edit();
			e.putBoolean(context.getString(R.string.prefTimerOnOff), false);
			e.commit();
		}
		else if (action.equals(SAVE))
		{
			Intent service = new Intent(context, WidgetService.class);
			context.stopService(service);
			
			TimerManager tm = new TimerManager();
			tm.stopTimer(context);
			
	        SharedPreferences p = context.getSharedPreferences("pref", Activity.MODE_PRIVATE);
			long startTime = p.getLong(context.getString(R.string.prefStartTime), 0);
	        
			if (startTime == 0)
			{
				MilkUtil.showToast(context, "타이머가 시작 되지 않았습니다.");
				setResetData(context);
				return;
			}
			
			if (setSaveData(context))
			{
				MilkUtil.showToast(context, "저장에 성공 하였습니다.");
				setResetData(context);
				return;
			}
			else
			{
				MilkUtil.showToast(context, "저장에 실패 하였습니다. 개발자에게 문의 해주세요.");
				setResetData(context);
				return;
			}
		}
		else if (action.equals(TIMER))
		{
			setRemoteView(context);
			
			SharedPreferences p = context.getSharedPreferences("pref", Activity.MODE_PRIVATE);
			int hour = p.getInt(context.getString(R.string.prefHour), 0);
			int min = p.getInt(context.getString(R.string.prefMin), 0);
			int sec = p.getInt(context.getString(R.string.prefSec), 0);
			
			remoteView.setTextViewText(R.id.widgetTimeTextView, MilkUtil.getTimeNo(
					hour, min, sec));
			
			setWidget(context);
			
			if (hour >= 23 && min >= 59 && sec >= 59)
			{
				Intent service = new Intent(context, WidgetService.class);
				context.stopService(service);
				
				TimerManager tm = new TimerManager();
				tm.stopTimer(context);
				
		        MilkUtil.showToast(context, "최대 시간은 23시 59분 59초를 넘길 수 없어요.");
				return;
			}
		}
	}

	private void setResetData(Context context)
	{
        SharedPreferences p = context.getSharedPreferences("pref", Activity.MODE_PRIVATE);
		SharedPreferences.Editor e = p.edit();
		e.putLong(context.getString(R.string.prefStartTime), 0);
		e.putInt(context.getString(R.string.prefHour), 0);
		e.putInt(context.getString(R.string.prefMin), 0);
		e.putInt(context.getString(R.string.prefSec), 0);
		e.putBoolean(context.getString(R.string.prefTimerOnOff), false);
		e.commit();
		
		setRemoteView(context);
		
		remoteView.setTextViewText(R.id.widgetTimeTextView, MilkUtil.getTimeNo(0, 0, 0));
		
		setWidget(context);
	}
	
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds)
	{
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		
		SharedPreferences p = context.getSharedPreferences("pref", Activity.MODE_PRIVATE);
		long startTime = p.getLong(context.getString(R.string.prefStartTime), 0);
		
		boolean timerOnOff = p.getBoolean(context.getString(R.string.prefTimerOnOff), false);
		int hour = p.getInt(context.getString(R.string.prefHour), 0);
		int min = p.getInt(context.getString(R.string.prefMin), 0);
		int sec = p.getInt(context.getString(R.string.prefSec), 0);
		
		setRemoteView(context);
		
		if (startTime != 0)
		{
			Calendar calN = Calendar.getInstance();
			calN.setTimeInMillis(0);
			calN.add(Calendar.HOUR_OF_DAY, hour);
			calN.add(Calendar.MINUTE, min);
			calN.add(Calendar.SECOND, sec);
			
			long termTime = calN.getTimeInMillis();
			
			Calendar calM = Calendar.getInstance();
			calM.setTimeInMillis(0);
			calM.add(Calendar.HOUR_OF_DAY, 23);
			calM.add(Calendar.MINUTE, 59);
			calM.add(Calendar.SECOND, 59);
			
			long hour24 = calM.getTimeInMillis();
			
			if (termTime >= hour24)
			{
		        MilkUtil.showToast(context, "최대 시간은 23시 59분 59초를 넘길 수 없어요.");
				
		        hour = 23;
		        min = 59;
		        sec = 59;
				
				remoteView.setTextViewText(R.id.widgetTimeTextView, MilkUtil.getTimeNo(hour, min, sec));
				
				Intent service = new Intent(context, WidgetService.class);
				context.stopService(service);
				
				TimerManager tm = new TimerManager();
				tm.stopTimer(context);
			}
			else
			{
				remoteView.setTextViewText(R.id.widgetTimeTextView, MilkUtil.getTimeNo(hour, min, sec));
				
				if (timerOnOff)
				{
					startTime(context);
				}
				else 
				{
					Intent service = new Intent(context, WidgetService.class);
					context.stopService(service);
					
					TimerManager tm = new TimerManager();
					tm.stopTimer(context);
				}
			}
		}
		else
		{
			hour = 0;
			min = 0;
			sec = 0;
			
			remoteView.setTextViewText(R.id.widgetTimeTextView, MilkUtil.getTimeNo(hour, min, sec));
			
			Intent service = new Intent(context, WidgetService.class);
			context.stopService(service);
			
			TimerManager tm = new TimerManager();
			tm.stopTimer(context);
		}
		
		setWidget(context);
	}

	private void setWidget(Context context)
	{
		AppWidgetManager manager = AppWidgetManager.getInstance(context);
		ComponentName componentName = new ComponentName(context, ToiletWidget.class);
		manager.updateAppWidget(componentName, remoteView);
	}

	private void setRemoteView(Context context)
	{
		remoteView = new RemoteViews(context.getPackageName(), R.layout.widget_4x2);
		
		Intent intent1 = new Intent(RESET);
		PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 
				0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
		remoteView.setOnClickPendingIntent(R.id.widgetResetView, pendingIntent1);
		
		Intent intent2 = new Intent(START);
		PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 
				0, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
		remoteView.setOnClickPendingIntent(R.id.widgetStartView, pendingIntent2);
		
		Intent intent3 = new Intent(STOP);
		PendingIntent pendingIntent3 = PendingIntent.getBroadcast(context, 
				0, intent3, PendingIntent.FLAG_UPDATE_CURRENT);
		remoteView.setOnClickPendingIntent(R.id.widgetStopView, pendingIntent3);
		
		Intent intent4 = new Intent(SAVE);
		PendingIntent pendingIntent4 = PendingIntent.getBroadcast(context, 
				0, intent4, PendingIntent.FLAG_UPDATE_CURRENT);
		remoteView.setOnClickPendingIntent(R.id.widgetSaveView, pendingIntent4);
		
		Intent intent5 = new Intent(context, IntroActivity.class);
		PendingIntent pendingIntent5 = PendingIntent.getActivity(context, 
				0, intent5, PendingIntent.FLAG_UPDATE_CURRENT);
		remoteView.setOnClickPendingIntent(R.id.widgetTimerView, pendingIntent5);
	}
	
	@Override
	public void onEnabled(Context context)
	{
		super.onEnabled(context);
		
		// 메모리 제거시 죽일 프로세스에 선택되지 않도록 하는 코드
		PackageManager pm = context.getPackageManager();
		pm.setComponentEnabledSetting(
				new ComponentName("constant.milk.toilet", "constant.milk.toilet.widget.ToiletWidget"),
				PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
				PackageManager.DONT_KILL_APP);
	}
	
	@Override
	public void onDisabled(Context context)
	{
		super.onDisabled(context);
		
		Intent service = new Intent(context, WidgetService.class);
		context.stopService(service);
	}
	
	private void startTime(final Context context)
	{
		SharedPreferences p = context.getSharedPreferences("pref", Activity.MODE_PRIVATE);
		SharedPreferences.Editor e = p.edit();
		e.putBoolean(context.getString(R.string.prefTimerOnOff), true);
		e.commit();
		
		TimerManager tm = new TimerManager();
		tm.startTimer(context);
		
		if (!isServiceRunning("constant.milk.toilet.timer.WidgetService", context))
		{
			Intent service = new Intent(context, WidgetService.class);
			context.startService(service);
		}
	}
	
	private boolean setSaveData(Context context)
	{
		DbInsertQuery query = null;
		
		try
		{
			query = new DbInsertQuery(context, DbAdapter.getInstance());
			
			query.setBeginTansaction();
			
			SharedPreferences p = context.getSharedPreferences("pref", Activity.MODE_PRIVATE);
			
			HashMap<String, String> map = new HashMap<String, String>();
			
			Calendar cal = Calendar.getInstance();
			int year = cal.get(Calendar.YEAR);
			int month = cal.get(Calendar.MONTH);
			int day = cal.get(Calendar.DAY_OF_MONTH);
			
			long startTime = p.getLong(context.getString(R.string.prefStartTime), 0);
					
			map.put("year", year + "");
			map.put("month", month + "");
			map.put("day", day + "");
			map.put("starttime", startTime + "");
			
			int hour = p.getInt(context.getString(R.string.prefHour), 0);
			int min = p.getInt(context.getString(R.string.prefMin), 0);
			int sec = p.getInt(context.getString(R.string.prefSec), 0);
			
			Calendar calT = Calendar.getInstance();
			calT.setTimeInMillis(0);
			calT.add(Calendar.HOUR_OF_DAY, hour);
			calT.add(Calendar.MINUTE, min);
			calT.add(Calendar.SECOND, sec);
			
			Calendar calM = Calendar.getInstance();
			calM.setTimeInMillis(0);
			calM.add(Calendar.HOUR_OF_DAY, 23);
			calM.add(Calendar.MINUTE, 59);
			calM.add(Calendar.SECOND, 59);
			
			long termTime = calT.getTimeInMillis();
			
			long hour24 = calM.getTimeInMillis();
			
			if (termTime >= hour24)
			{
				termTime = hour24;
			}
			
			map.put("term", termTime + "");
			
			query.insertTimer(map);
			
			int alarmPush = p.getInt(context.getString(R.string.prefPushAlarm), 1);
			
			if (alarmPush > 1)
			{
				Intent intent = new Intent(context, PushBroadcast.class);    
				PendingIntent sender = PendingIntent.getBroadcast(context, 1, intent, 
						PendingIntent.FLAG_CANCEL_CURRENT);
				
		        AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
		        manager.cancel(sender);
		        
		        int version = Build.VERSION.SDK_INT;
				
				if (version >= 19)
				{
					manager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (24 * 60 * 60000), sender);
				}
				else
				{
					manager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (24 * 60 * 60000), sender);
				}
		        
		        SharedPreferences.Editor e = p.edit();
		        
		        e.putInt(context.getString(R.string.prefPushAlarm), 1);
		        e.commit();
			}
			
			query.setSuccessful();
		} catch (Exception e)
		{
			e.printStackTrace();
			return false;
		} finally {
			try
			{
				query.setEndTansaction();
			} catch (Exception e)
			{
				e.printStackTrace();
				return false;
			}
		}
		
		return true;
	}
	
	public Boolean isServiceRunning(String serviceName, Context context)
	{
		ActivityManager activityManager = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);

		for (RunningServiceInfo runningServiceInfo : activityManager.getRunningServices(Integer.MAX_VALUE))
		{
			if (serviceName.equals(runningServiceInfo.service.getClassName()))
			{
				return true;
			}
		}

		return false;
	}
}
